import {
  WebSocketGateway,
  SubscribeMessage,
  ConnectedSocket,
  MessageBody,
  WebSocketServer,
} from '@nestjs/websockets';
import { Socket, Server } from 'socket.io';
import { RedisCacheService } from '../../redis-cache/redis-cache.service';

@WebSocketGateway(9999, {
  cors: { origin: '*' },
})
// @WebSocketGateway({ cors: { origin: '*' } })
export class EventGateway {
  count: number;
  @WebSocketServer()
  server: Server;
  userList: Map<string, any>;
  users: any;
  usersMessageList: any;
  usersGroupMessageList: any;

  constructor(private readonlyRedisCacheService: RedisCacheService) {
    this.users = {};
    this.userList = new Map<string, any>();
  }
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  handleConnection(client: Socket) {
    this.server.emit('gropUser', this.filterGroupUser());
  }

  handleDisconnect(client: Socket) {
    client.on('on_close', (user: any) => {
      this.userList.delete(user.name);
      this.server.emit('gropUser', this.filterGroupUser());
    });
    this.server.emit('gropUser', this.filterGroupUser());
  }

  @SubscribeMessage('events')
  handleEvent(@MessageBody() body: any, @ConnectedSocket() client: Socket) {
    this.users[body.name] = client.id;
    this.users['messageLen'] = 0;
    this.usersMessageList = [];
    this.usersGroupMessageList = [];
    if (!this.userList.has(body.name)) {
      this.userList.set(body.name, body);
      this.server.emit('gropUser', this.filterGroupUser());
    }
    this.server.emit('currentUserCount', {
      name: body.name,
      avatarImagUrl: body.imageUrl,
      currentOnlien: `${body.name}上线了`,
      socketId: client.id,
      currrentUserNum: this.userList.size,
    });

    // 客户端主动退出
    client.on('on_close', (user: any) => {
      this.server.emit('currentUserCount', {
        name: user.name,
        socketId: client.id,
        currrentUserNum: this.userList.size,
      });
      this.userList.delete(user.name);
      this.server.emit('gropUser', this.filterGroupUser());
    });

    // 删除指定聊天记录
    client.on('deleteMessage', async (userName: string) => {
      await this.readonlyRedisCacheService.delete(userName);
    });

    // 查询私聊聊天记录
    client.on('queryMessage', async (userName: string) => {
      const data = await this.readonlyRedisCacheService.get(userName);
      if (data === null) {
        client.emit('ChatHistory', []);
        return;
      }
      client.emit('ChatHistory', data);
    });

    // 查询群聊聊天记录
    client.on('queryGroupMessage', async (groupName: string) => {
      const data = await this.readonlyRedisCacheService.get(groupName);
      if (data === null) {
        client.emit('GroupChatHistory', []);
        return;
      }
      client.emit('GroupChatHistory', data);
    });

    // 设置已读消息
    client.on('setReadMessage', async (personalData: any) => {
      this.userList.get(personalData.sendUserName).view = true;
      this.userList.get(personalData.name).messageLen = 0;
      const history = await this.readonlyRedisCacheService.get(personalData.name);
      const sendhistory = await this.readonlyRedisCacheService.get(personalData.sendUserName);
      if (history !== null && sendhistory !== null) {
        if (!personalData.viewType && sendhistory !== null) {
          // 某个用户单个窗口已读处理
          sendhistory.forEach((item: any) => {
            item.isRead = false;
          });
          this.readonlyRedisCacheService.set(personalData.sendUserName, sendhistory);
          this.server.to(personalData.userId).emit('read-reolad', 'reload');
          this.server.emit('gropUser', this.filterGroupUser()); // 更新用户信息
          return;
        } else {
          // 某双方用户个窗口都在开启状态已读消息处理
          history.forEach((item: any) => {
            item.isRead = false;
          });
          sendhistory.forEach((item: any) => {
            item.isRead = false;
          });
          this.readonlyRedisCacheService.set(personalData.name, history);
          this.readonlyRedisCacheService.set(personalData.sendUserName, sendhistory);
          this.server.to(personalData.userId).emit('read-reolad', 'reload');
          this.server.emit('gropUser', this.filterGroupUser()); // 更新用户信息
        }
      }
      this.server.emit('gropUser', this.filterGroupUser());
    });

    // 用户关闭了窗口
    client.on('closeWindow', async (userName: string) => {
      if (this.userList.get(userName)) {
        this.userList.get(userName).view = false;
        this.server.emit('gropUser', this.filterGroupUser());
      }
    });
    // 群聊消息撤回处理
    client.on('revoke-group-message', async (userGroupName: string, messageId: string) => {
      const currentGroupData = await this.readonlyRedisCacheService.get(userGroupName);
      // 将消息数据查出后修改属性为撤回数据
      if (currentGroupData !== null) {
        currentGroupData.forEach((item: any) => {
          if (item.id === messageId) {
            item.withdraw = true;
          }
        });
        this.readonlyRedisCacheService.set(userGroupName, currentGroupData);
        this.server.emit('read-reolad', 'groupReload');
      }
    });
    // 处理私聊消息撤回
    client.on('revoke-private-message', async (user: any, messageId: string) => {
      const history = await this.readonlyRedisCacheService.get(user.name);
      const sendhistory = await this.readonlyRedisCacheService.get(user.sendName);
      if (history !== null && sendhistory !== null) {
        history.forEach((item: any) => {
          if (item.id === messageId) {
            item.withdraw = true;
          }
        });
        sendhistory.forEach((item: any) => {
          if (item.id === messageId) {
            item.withdraw = true;
          }
        });
        this.readonlyRedisCacheService.set(user.name, history);
        this.readonlyRedisCacheService.set(user.sendName, sendhistory);
        this.server.to(user.socketId).emit('read-reolad', 'private');
      }
    });

    //建立私聊连接
    client.on('personal', async (personalData: any) => {
      const data = {
        user: personalData.user,
        message: '单聊模式切换成功',
      };
      personalData.user.messageLen = this.userList.get(personalData.user.sendUserName).messageLen +=
        1;
      // 将之前的聊天记录查出来尾部添加后存储
      const history = await this.readonlyRedisCacheService.get(personalData.user.name);
      const sendhistory = await this.readonlyRedisCacheService.get(personalData.user.sendUserName);
      if (history !== null && sendhistory !== null) {
        history.push(personalData.user);
        sendhistory.push(personalData.user);
        this.readonlyRedisCacheService.set(personalData.user.sendUserName, sendhistory);
        this.readonlyRedisCacheService.set(personalData.user.name, history);
        this.server.to(personalData.userId).emit('personalSend', data);
        return;
      }
      this.readonlyRedisCacheService.set(personalData.user.sendUserName, [personalData.user]);
      this.readonlyRedisCacheService.set(personalData.user.name, [personalData.user]);
      this.server.to(personalData.userId).emit('personalSend', data);
    });

    client.on('group', async (messageData: any) => {
      const groupHistory = await this.readonlyRedisCacheService.get('groupMessageList');
      if (groupHistory !== null) {
        groupHistory.push(messageData);
        this.readonlyRedisCacheService.set('groupMessageList', groupHistory);
        this.server.emit('groupMessage', messageData);
        return;
      }
      this.readonlyRedisCacheService.set('groupMessageList', [messageData]);
      this.server.emit('groupMessage', messageData);
    });

    this.server.emit('gropUser', this.filterGroupUser());
  }

  filterGroupUser() {
    const arr = [];
    const userList = Object.fromEntries(this.userList.entries());
    for (const key in userList) {
      arr.push({
        name: userList[key].name,
        imageUrl: userList[key].imageUrl ?? '',
        socketId: this.users[userList[key].name],
        messageLen: userList[key].messageLen,
        view: userList[key].view,
      });
    }
    return arr;
  }
}
